💡 AI 인사이트

🤖 AI가 여기에 결과를 출력합니다...

댓글 커뮤니티

쿠팡이벤트

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

검색

    로딩 중이에요... 🐣

    [코담] 웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트

    07 Form 처리와 Generic View 활용 | ✅ 편저: 코담 운영자

    Django 웹 프로그래밍 강좌 7강 - Form 처리와 Generic View 활용 (Django 5.2 기준)

    강의 영상:

    이 강의는 Django 공식 문서의 2.2 튜토리얼 내용을 바탕으로 진행되며, Django 5.2 버전에 맞춰 코드를 업그레이드하여 설명합니다.

    📚 공식문서 주소: https://docs.djangoproject.com/ko/5.2/intro/tutorial04/


    1. 사용자 입력 처리: Form 태그 구조 이해

    HTML의 <form> 태그는 사용자의 입력을 서버로 전달하는 핵심 구조입니다.

    detail.html 내 form 구성 예시:

    <form action="{% url 'polls:vote' question.id %}" method="post">
        {% csrf_token %}
        {% for choice in question.choice_set.all %}
            <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
            <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
        {% endfor %}
        <input type="submit" value="Vote">
    </form>
    
    • action: 데이터를 보낼 URL 경로
    • method="post": 데이터를 서버로 전송하는 방식
    • {% csrf_token %}: Django 보안을 위한 필수 태그
    • radio: 단일 항목 선택을 위한 입력 필드
    • value: 선택된 항목의 고유 ID

    Django는 CSRF 공격을 방지하기 위해 POST 요청 시 보안 토큰을 요구합니다.


    2. Form에서 View로 데이터 처리 흐름

    vote() 뷰 함수 (polls/views.py):

    from django.shortcuts import get_object_or_404, render
    from django.http import HttpResponseRedirect
    from django.urls import reverse
    from .models import Question, Choice
    
    def vote(request, question_id):
        question = get_object_or_404(Question, pk=question_id)
        try:
            selected_choice = question.choice_set.get(pk=request.POST["choice"])
        except (KeyError, Choice.DoesNotExist):
            return render(request, "polls/detail.html", {
                "question": question,
                "error_message": "선택이 필요합니다.",
            })
        else:
            selected_choice.votes += 1
            selected_choice.save()
            return HttpResponseRedirect(reverse("polls:results", args=(question.id,)))
    
    • request.POST["choice"]로 전송된 데이터 추출
    • 선택값이 없거나 잘못된 경우 예외 처리 후 에러 메시지 출력
    • 올바른 선택이면 vote 수 증가 후 저장 → 결과 페이지로 리디렉션

    reverse() 함수는 URL 패턴 이름 기반으로 URL을 생성하며, 하드코딩을 방지합니다.


    3. 결과 페이지 구성

    결과 View (polls/views.py):

    def results(request, question_id):
        question = get_object_or_404(Question, pk=question_id)
        return render(request, "polls/results.html", {"question": question})
    

    결과 템플릿 (polls/templates/polls/results.html):

    <h1>{{ question.question_text }}</h1>
    <ul>
    {% for choice in question.choice_set.all %}
        <li>{{ choice.choice_text }} — {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
    {% endfor %}
    </ul>
    <a href="{% url 'polls:detail' question.id %}">다시 투표하기</a>
    
    • pluralize 필터는 1표 vs 복수 표의 언어 처리에 유용

    4. 함수 기반 View vs 클래스 기반 View (Generic View)

    Django는 중복되는 View 코드를 줄이기 위해 Generic Class-Based Views(CBV)를 제공합니다.

    Generic View 예시 (views.py):

    from django.views import generic
    from .models import Question
    
    class IndexView(generic.ListView):
        template_name = "polls/index.html"
        context_object_name = "latest_question_list"
    
        def get_queryset(self):
            return Question.objects.order_by("-pub_date")[:5]
    
    class DetailView(generic.DetailView):
        model = Question
        template_name = "polls/detail.html"
    
    class ResultsView(generic.DetailView):
        model = Question
        template_name = "polls/results.html"
    
    • ListView: 객체 목록 뷰
    • DetailView: 특정 객체 상세 뷰
    • get_queryset()은 보여줄 데이터 범위 지정

    URLconf 변경 (polls/urls.py):

    from . import views
    
    app_name = "polls"
    
    urlpatterns = [
        path("", views.IndexView.as_view(), name="index"),
        path("<int:pk>/", views.DetailView.as_view(), name="detail"),
        path("<int:pk>/results/", views.ResultsView.as_view(), name="results"),
        path("<int:question_id>/vote/", views.vote, name="vote"),
    ]
    
    • Generic View는 기본적으로 pk 파라미터를 객체 식별자로 사용합니다.

    Generic View는 빠른 개발을 가능하게 하며, 반복 코드를 줄일 수 있습니다.


    마무리 요약

    • Form을 통해 사용자 입력을 서버로 전달하고 처리 가능
    • CSRF 보호와 POST 방식은 Django에서 기본 보안 요소
    • request.POST[]로 입력값 추출 후, 모델에 반영하여 저장
    • reverse()를 사용하여 URL 하드코딩을 방지
    • Generic View는 클래스를 기반으로 반복 코드를 줄이고, 유지보수가 쉽다

    다음 강의 예고

    8강에서는 **단위 테스트(TestCase)**를 사용하여 뷰와 모델의 동작을 자동으로 검증하는 방법을 학습합니다.

    감사합니다.

    TOP
    preload preload